package com.whmskj.xjlhsc.service.impl;
import com.whmskj.xjlhsc.mobie.Scheduling.entity.yg01EmployeeFiles;
import com.whmskj.xjlhsc.mobie.Scheduling.mapper.EmployeeFilesMapper;
import com.whmskj.xjlhsc.entity.Grouptableyg02;
import com.whmskj.xjlhsc.entity.Managementofxt03;
import com.whmskj.xjlhsc.mapper.Grouptableyg02Mapper;
import com.whmskj.xjlhsc.mapper.Managementofxt03Mapper;
import com.whmskj.xjlhsc.mapper.SectorXt01Mapper;
import com.whmskj.xjlhsc.mapper.JobXt02Mapper;
import com.whmskj.xjlhsc.service.AttendanceNamingService;
import com.whmskj.xjlhsc.mobie.empProPlan.entity.ProPersonnelStandConfirm;
import com.whmskj.xjlhsc.mobie.empProPlan.mapper.ProPersonnelStandConfirmMapper;
import com.whmskj.xjlhsc.entity.PasswordAuth;
import com.whmskj.xjlhsc.mapper.AttendancePasswordAuthMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.hutool.crypto.digest.MD5;

import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AttendanceNamingServiceImpl implements AttendanceNamingService {

    @Autowired
    private EmployeeFilesMapper employeeFilesMapper;
    
    @Autowired
    private SectorXt01Mapper sectorXt01Mapper;
    @Autowired
    private JobXt02Mapper jobXt02Mapper;

    @Autowired
    private Managementofxt03Mapper managementofxt03Mapper; // 工种表

    @Autowired
    private Grouptableyg02Mapper grouptableyg02Mapper; // 班组表
    
    @Autowired
    private ProPersonnelStandConfirmMapper proPersonnelStandConfirmMapper; // 人员看台组长确认临时表
    
    @Autowired
    private AttendancePasswordAuthMapper attendancePasswordAuthMapper; // 密码认证表

    // 部门
    @Override
    public List<String> listDepartmentNames() {
        return sectorXt01Mapper != null ? sectorXt01Mapper.listSectorNames()
                : List.of();
    }

    // 工种
    @Override
    public List<String> listJobTypeNames() {
        List<Managementofxt03> list = managementofxt03Mapper.selectList(null);
        return list.stream().map(Managementofxt03::getNameofjob).collect(Collectors.toList());
    }

    // 岗位
    @Override
    public List<String> listPositionNames() {
        return jobXt02Mapper != null ? jobXt02Mapper.listPositionNames() : List.of();
    }

    // 班组
    @Override
    public List<String> listGroupNames() {
        List<Grouptableyg02> list = grouptableyg02Mapper.selectList(null);
        return list.stream().map(Grouptableyg02::getClassname).collect(Collectors.toList());
    }

    // 早班/晚班
    @Override
    public String detectCurrentShift() {
        // 规则：09:00-21:00 为早班；21:00-次日09:00 为晚班
        LocalTime now = LocalTime.now();
        LocalTime dayStart = LocalTime.of(9, 0);
        LocalTime dayEnd = LocalTime.of(21, 0);
        return (now.equals(dayStart) || now.isAfter(dayStart)) && now.isBefore(dayEnd) ? "早班" : "晚班";
    }

    // 人员筛选
    @Override
    public List<yg01EmployeeFiles> filterEmployees(String department, String jobType, String position, String group) {
        yg01EmployeeFiles param = new yg01EmployeeFiles();
        // 仅根据名称字段做等值过滤
        return employeeFilesMapper.selectEmployeeFilesList(param).stream()
                .filter(e -> department == null || department.equals(e.getSector()))
                .filter(e -> jobType == null || jobType.equals(e.getTypeOfWork()))
                .filter(e -> position == null || position.equals(e.getPositions()))
                .filter(e -> group == null || group.equals(e.getClass55()))
                .collect(Collectors.toList());
    }

    @Override
    public boolean validateLogin(String username, String password) {
        try {
            // 直接查询password_auth表进行登录验证
            LambdaQueryWrapper<PasswordAuth> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PasswordAuth::getUsername, username);
            PasswordAuth passwordAuth = attendancePasswordAuthMapper.selectOne(wrapper);
            
            if (passwordAuth == null) {
                return false; // 账号不存在
            }
            
            // 验证密码（使用与XJLHBC模块相同的加密逻辑）
            String storedPassword = passwordAuth.getPassword();
            String[] parts = storedPassword.split("#");
            if (parts.length != 2) {
                return false; // 密码格式错误
            }
            
            String str = parts[0];        // 加密后的密码
            String str1 = parts[1];      // 盐值
            
            // 对输入密码进行相同加密
            String passwordMd5 = MD5.create().digestHex(password);
            String digest = MD5.create().digestHex(passwordMd5 + str1);
            
            // 比较加密结果
            return str.equals(digest);
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public String getCurrentAttendant(String username) {
        try {
            // 账号即手机号：优先使用手机号(contactCall)匹配当前登录人
            // 由于XML筛选项未包含 contactCall，这里统一拉取后在内存中过滤
            List<yg01EmployeeFiles> all = employeeFilesMapper.selectEmployeeFilesList(new yg01EmployeeFiles());
            yg01EmployeeFiles currentUser = all.stream()
                    .filter(emp -> username.equals(emp.getContactCall())) // 先按手机号匹配
                    .findFirst()
                    .orElseGet(() ->
                            all.stream().filter(emp -> username.equals(emp.getName())) // 兜底按姓名匹配
                                    .findFirst().orElse(null)
                    );

            // 返回当前登录人的姓名作为考勤人（classes 字段存放的是考勤人姓名）
            return currentUser != null ? currentUser.getName() : null;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<yg01EmployeeFiles> getUnauthorizedEmployees(List<Integer> employeeIds, String currentAttendant) {
        try {
            // 获取所有选中的员工
            List<yg01EmployeeFiles> allEmployees = employeeFilesMapper.selectEmployeeFilesList(new yg01EmployeeFiles());
            
            String attendantNorm = normalize(currentAttendant);
            // 筛选出无权限的员工（当前登录人不是这些员工的考勤人）
            return allEmployees.stream()
                    .filter(emp -> employeeIds.contains(emp.getId()))
                    .filter(emp -> {
                        String cls = normalize(emp.getClasses());
                        // classes为空或与当前登录人姓名不一致，都视为无权限
                        return cls.isEmpty() || !cls.equalsIgnoreCase(attendantNorm);
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return List.of();
        }
    }

    /**
     * 规范化字符串：去除前后空白、所有空白字符与不可见空格
     */
    private String normalize(String str){
        if(str == null) return "";
        // 去除各类空白字符（包括全角空格）、零宽字符
        String s = str.replaceAll("\\s+", "").replace("\u00A0"," ").trim();
        return s;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmAttendanceAndInsert(List<Integer> employeeIds, String currentAttendant) {
        try {
            // 获取当前日期时间（与库中 datetime 类型兼容）
            java.time.format.DateTimeFormatter dtf = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String today = java.time.LocalDateTime.now().format(dtf);
            String shift = detectCurrentShift();
            
            // 获取员工信息
            List<yg01EmployeeFiles> employees = employeeFilesMapper.selectEmployeeFilesList(new yg01EmployeeFiles());
            List<yg01EmployeeFiles> targetEmployees = employees.stream()
                    .filter(emp -> employeeIds.contains(emp.getId()))
                    .collect(Collectors.toList());

            // 校验：传入的员工ID必须全部存在；否则不进行任何插入
            java.util.Set<Integer> foundIds = targetEmployees.stream().map(yg01EmployeeFiles::getId).collect(java.util.stream.Collectors.toSet());
            boolean allExist = employeeIds != null && foundIds.size() == employeeIds.stream().distinct().count();
            if (!allExist) {
                return false;
            }

            // 取得当前登录人的员工ID（用于 create_user_id）
            Integer currentUserId = employees.stream()
                    .filter(emp -> currentAttendant.equals(emp.getName()))
                    .map(yg01EmployeeFiles::getId)
                    .findFirst()
                    .orElse(null);
            
            // 为每个员工创建/更新确认记录
            for (yg01EmployeeFiles employee : targetEmployees) {
                ProPersonnelStandConfirm confirm = new ProPersonnelStandConfirm();
                
                // 设置基本信息
                confirm.setDateYmd(today);
                confirm.setStaffId(employee.getId());
                // 通过班组名称(class55)反查班组ID
                Integer teamId = null;
                try {
                    com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Grouptableyg02> teamWrapper = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
                    teamWrapper.eq(Grouptableyg02::getClassname, employee.getClass55());
                    Grouptableyg02 team = grouptableyg02Mapper.selectOne(teamWrapper);
                    if (team != null) teamId = team.getId();
                } catch (Exception ignore) {}
                confirm.setTeamId(teamId);
                confirm.setTeamName(employee.getClass55()); // 班组名称
                confirm.setClasses(shift); // 早班/晚班
                confirm.setProcess(employee.getPositions()); // 工序
                confirm.setWorkshop(employee.getSector()); // 车间
                confirm.setConfirmStatus("CONFIRMED"); // 确认状态
                if (currentUserId != null) {
                    confirm.setCreateUserId(Long.valueOf(currentUserId)); // 创建人ID（考勤人）
                }
                confirm.setCreateTime(new Date()); // 创建时间
                confirm.setRemark("考勤确认");
                
                // 查询当天该班次是否已有记录
                com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProPersonnelStandConfirm> existQuery =
                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
                String dayPrefix = today.substring(0, 10); // yyyy-MM-dd
                existQuery.eq(ProPersonnelStandConfirm::getStaffId, employee.getId())
                        .eq(ProPersonnelStandConfirm::getClasses, shift)
                        .likeRight(ProPersonnelStandConfirm::getDateYmd, dayPrefix);

                ProPersonnelStandConfirm existed = proPersonnelStandConfirmMapper.selectOne(existQuery);

                if (existed != null) {
                    // 已有记录：若未确认，则只更新状态为 CONFIRMED；若已确认，直接跳过不再插入
                    if (!"CONFIRMED".equalsIgnoreCase(existed.getConfirmStatus())) {
                        ProPersonnelStandConfirm toUpdate = new ProPersonnelStandConfirm();
                        toUpdate.setId(existed.getId());
                        toUpdate.setConfirmStatus("CONFIRMED");
                        proPersonnelStandConfirmMapper.updateById(toUpdate);
                    }
                    continue; // 无论如何都不再新增
                }

                // 插入新数据
                proPersonnelStandConfirmMapper.insert(confirm);
            }
            
            return true;
        } catch (Exception e) {
            throw new RuntimeException("考勤确认插入数据失败: " + e.getMessage(), e);
        }
    }

    @Override
    public com.baomidou.mybatisplus.extension.plugins.pagination.Page<java.util.Map<String, Object>> pageRecords(
            com.whmskj.xjlhsc.service.dto.ConfirmQuery query) {
        int pageNo = query.getPageNo() == null || query.getPageNo() < 1 ? 1 : query.getPageNo();
        int pageSize = query.getPageSize() == null || query.getPageSize() < 1 ? 10 : query.getPageSize();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<java.util.Map<String, Object>> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        return proPersonnelStandConfirmMapper.selectPageWithFilter(page, query);
    }

    @Override
    public java.util.List<yg01EmployeeFiles> listEmployeesAuditedByCurrent() {
        // 考勤人字段(classes)只存姓名，直接用登录人姓名精确匹配
        String attendantName = com.whmskj.xjlhsc.utils.SCUtil.getCurrentLoginEmp().getEmpName();
        List<yg01EmployeeFiles> all = employeeFilesMapper.selectEmployeeFilesList(new yg01EmployeeFiles());
        return all.stream()
                .filter(e -> attendantName.equals(e.getClasses()))
                .collect(java.util.stream.Collectors.toList());
    }
}


